package com.rightsidetech.activity.service.impl;

import com.gexin.fastjson.JSONArray;
import com.rightsidetech.activity.dto.request.ActCouponCountInfoReq;
import com.rightsidetech.activity.dto.request.ActGetCouponReq;
import com.rightsidetech.activity.dto.request.ActGetStoreCouponReq;
import com.rightsidetech.activity.dto.response.ActCouponAllResp;
import com.rightsidetech.activity.dto.response.ActCouponCountInfoResp;
import com.rightsidetech.activity.dto.response.ActCouponStoreGetResp;
import com.rightsidetech.activity.dto.response.ActFindCouponResp;
import com.rightsidetech.activity.entity.*;
import com.rightsidetech.activity.mapper.*;
import com.rightsidetech.activity.service.ActCouponUserService;
import com.rightsidetech.commom.base.ResponseData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author: yhr
 * @Date: 2022-01-10 14:07
 */
@Service("actCouponUserService")
@Slf4j
public class ActCouponUserServiceImpl implements ActCouponUserService {
    @Resource
    private ActCouponActivityMapper actCouponActivityMapper;
    @Resource
    private ActCouponActivityStatisMapper actCouponActivityStatisMapper;
    @Resource
    private ActCouponActivityCodeMapper actCouponActivityCodeMapper;
    @Resource
    private ActCouponGetRecordMapper actCouponGetRecordMapper;
    @Resource
    private ActCouponBaseInfoMapper actCouponBaseInfoMapper;
    @Resource
    private ActCouponUsedRecordMapper actCouponUsedRecordMapper;

    @Override
    public synchronized ResponseData getCoupon(ActGetCouponReq req, Long level) {
        List<ActCouponActivity> actCouponActivityList = null;
        if(req.getActivityId().isEmpty() || req.getActivityId().size() <= 0){
            //查询可以参加的活动
            actCouponActivityList = actCouponActivityMapper.selectUsedActivity();
        }else{
            //去重
            List<Long>  list = new ArrayList<>(new TreeSet<>(req.getActivityId()));
            actCouponActivityList = actCouponActivityMapper.selectUsedActivityByActivityIds(list);
        }
        if(actCouponActivityList.isEmpty()){
            return ResponseData.fail("没有可领取优惠券的活动");
        }

        for (ActCouponActivity activity:actCouponActivityList) {

            if (!StringUtils.isEmpty(activity.getLevel()) && activity.getLevel() != -1){
                if (level < activity.getLevel()){
                    ResponseData.fail("用户等级未达到要求");
                    log.info("用户等级未达到要求,activityId={}",activity.getId());
                    continue;
                }
            }
            //判断该优惠活动是否还能领券
            List<ActCouponActivityCode> activityCodes = actCouponActivityCodeMapper.selectByActivityIdAndStatus(activity.getId(),(byte) 0);
            if(activityCodes.isEmpty() || activityCodes.size() <= 0){
                ResponseData.fail("该活动没有可领取的优惠券");
                log.info("该活动没有可领取的优惠券,activityId={}",activity.getId());
                continue;
            }
            //判断用户是否已经领取过该优惠券, 且领取的数量是否超过领取数量
            int haveCount = actCouponGetRecordMapper.selectCountByActivityIdAndUserIdAndStatus(activity.getId(),req.getUserInfoId(),(byte) 0);
            if(haveCount > 0){
                ResponseData.fail("用户存在使用的优惠券");
                log.info("用户存在领取未使用的优惠前,activityId={}",activity.getId());
                continue;
            }
            int totalCount = actCouponGetRecordMapper.selectCountByActivityIdAndUserId(activity.getId(),req.getUserInfoId());
            if(totalCount >= activity.getGetQuantity()){
                log.info("该活动下,用户已到达最多领取次数, activityId={}",activity.getId());
                continue;
            }

            ActCouponBaseInfo actCouponBaseInfo = actCouponBaseInfoMapper.selectByPrimaryKey(activity.getCouponBaseId());
            //获取一个优惠券
            int max = activityCodes.size(),min = 0;
            int index = (int) (Math.random()*(max-min)+min);
            ActCouponActivityCode activityCode = activityCodes.get(index);

            ActCouponGetRecord actCouponGetRecord = new ActCouponGetRecord();
            BeanUtils.copyProperties(activity,actCouponGetRecord);
            actCouponGetRecord.setId(null);
            actCouponGetRecord.setActivityId(activity.getId());
            actCouponGetRecord.setCode(activityCode.getCode());
            actCouponGetRecord.setUserStoreId(req.getUserInfoId());
            actCouponGetRecord.setUsUserName(req.getPetName());
            actCouponGetRecord.setPhoneNo(req.getPhoneNo());
            actCouponGetRecord.setTarget((byte) 0);
            actCouponGetRecord.setStatus((byte) 0);
            actCouponGetRecord.setCreatedAt(new Date());
            actCouponGetRecord.setCouponType(actCouponBaseInfo.getCouponType());
            actCouponGetRecord.setAmount(actCouponBaseInfo.getAmount());
            actCouponGetRecord.setUseScope(activity.getUseScope());

            actCouponGetRecordMapper.insertSelective(actCouponGetRecord);
            ActCouponActivityCode activityCode1 = new ActCouponActivityCode();
            activityCode1.setId(activityCode.getId());
            activityCode1.setUpdatedAt(new Date());
            activityCode1.setStatus((byte) 1);
            actCouponActivityCodeMapper.updateByPrimaryKeySelective(activityCode1);

/*            ActCouponActivityStatis activityStatis = actCouponActivityStatisMapper.selectByAcId(activity.getId());
            ActCouponActivityStatis statis = new ActCouponActivityStatis();
            statis.setCouponActivityId(activity.getId());
            statis.setReceiveNum(activityStatis.getReceiveNum()+1);
            statis.setUpdatedAt(new Date());
            actCouponActivityStatisMapper.updateByPrimaryKeySelective(statis);*/
        }

        return ResponseData.success();
    }

    @Override
    public List<ActCouponAllResp> couponCountInfo(Long loginInfoId, ActCouponCountInfoReq actCouponCountInfoReq) {
        List<ActCouponAllResp> allResps = actCouponGetRecordMapper.selectCanUseCoupon(loginInfoId, actCouponCountInfoReq.getAmount().longValue());
        return allResps;
    }


/*    @Override
    public void updateStatis(ActUpdateStatisReq req) {
        ActCouponActivityStatis acDate = actCouponActivityStatisMapper.selectByAcId(req.getActivityId());
        if(!ObjectUtils.isEmpty(acDate) ){
            ActCouponActivityStatis statis = new ActCouponActivityStatis();
            statis.setId(acDate.getId());
            statis.setUseNum(acDate.getUseNum()+1);
            statis.setTotalDiscountAmount(acDate.getTotalDiscountAmount().add(req.getDiscountAmount()));
            statis.setTotalPayAmount(acDate.getTotalPayAmount().add(req.getPayAmount()));
            statis.setTotalPayableAmount(acDate.getTotalPayableAmount().add(req.getPayableAmount()));
            statis.setUpdatedAt(new Date());
            actCouponActivityStatisMapper.updateByPrimaryKeySelective(statis);
        }
    }*/

    @Override
    public ResponseData<List<ActFindCouponResp>> findCoupon(Long level, Long userInfoId) {
        List<ActFindCouponResp> coupon = actCouponActivityMapper.findCoupon(level);
        Iterator<ActFindCouponResp> iterator = coupon.iterator();
        while(iterator.hasNext()){
            ActFindCouponResp resp = iterator.next();

            boolean flag = false;
            //判断该活动优惠券是否已经领取完
            Long unUserCount = actCouponActivityCodeMapper.selectByCouponActivityIdAndStatus(resp.getActivityId(),(byte) 0);
            if (unUserCount <= 0 ){
                iterator.remove();
                continue;
            }
            //已使用/领取使用的数量
            int useCount = actCouponGetRecordMapper.selectCountByActivityIdAndUserId(resp.getActivityId(), userInfoId);
            if (useCount >= resp.getMaxQuantity()){
                iterator.remove();
                continue;
            }
            //判断该活动用户是否已经领取优惠券
            int getCount = actCouponGetRecordMapper.selectCountByActivityIdAndUserIdAndStatus(resp.getActivityId(), userInfoId, (byte) 0);

            if (getCount > 0){
                iterator.remove();
                continue;
            }
        }
        return ResponseData.success(coupon);
    }

    @Override
    public ResponseData<List<ActCouponCountInfoResp>> cardBag(Long loginInfoId, Byte type) {
        return ResponseData.success(actCouponGetRecordMapper.cardBag(loginInfoId,type));
    }

    @Override
    public ResponseData<ActCouponCountInfoResp> codeInfo(String code, Long userInfoId, Long level) {
        ActCouponCountInfoResp actCouponCountInfoResp = actCouponGetRecordMapper.codeInfo(code,userInfoId);
        if(StringUtils.isEmpty(actCouponCountInfoResp)){
            return ResponseData.fail("优惠券不存在");
        }
        return ResponseData.success(actCouponCountInfoResp);
    }

/*    @Override
    public int updateByPrimaryKeySelective(ActCouponActivityStatis statis) {
        return actCouponActivityStatisMapper.updateByPrimaryKeySelective(statis);
    }*/

/*    @Override
    public int updateStatisCount(ActCouponActivityStatis statis) {
        return actCouponActivityStatisMapper.updateByPrimaryKeySelective(statis);
    }*/

/*    @Override
    public ActCouponActivityStatis selectByAcId(Long activityId) {
        return actCouponActivityStatisMapper.selectByAcId(activityId);
    }*/

    @Override
    public ResponseData<ActCouponStoreGetResp> getCodeByActivityNoAndAgentInfoId(ActGetStoreCouponReq req, Long agentId, Long userInfoId) {
        ActCouponStoreGetResp codeResp = new ActCouponStoreGetResp();
        ActCouponActivity activity = actCouponActivityMapper.findByActivityNo(req.getActivityNo());
        if(StringUtils.isEmpty(activity) || activity.getStatus() != 4 || activity.getTarget() != 1){
            return ResponseData.fail("无效二维码");
        }
        if(activity.getStartTime().getTime() > System.currentTimeMillis()){
            return ResponseData.fail("活动未开启");
        }
        if(activity.getEndTime().getTime() < System.currentTimeMillis()){
            return ResponseData.fail("活动已结束");
        }
        String useScope = activity.getUseScope();
        if(StringUtils.isEmpty(useScope)){
            return ResponseData.fail("活动范围不能为空");
        }
        List<Long> list = JSONArray.parseArray(useScope,Long.class);
        boolean flag = list.contains(agentId);
        if(!flag){
            return ResponseData.fail("不符合门店优惠券使用条件！");
        }
        //判断总金额是否超过活动最低消费金额
        if(!StringUtils.isEmpty(req.getTotalAmount())){
            if(req.getTotalAmount() < activity.getMinConsumeAmount()){
                return ResponseData.fail("订单金额不符合门店优惠券使用条件！");
            }
        }


        //判断该用户是否还能领取该活动的优惠券
/*        int userCount = actCouponUsedRecordMapper.selectCountByUserInfoIdAndActivityIdAndStatus(activity.getId(),userInfoId);
        if(userCount > 0){
            return ResponseData.fail("已经使用过优惠券");
        }*/
        //判断是否是用户优惠券

        //统计该门店还可以使用优惠券张数
        int storeCount = actCouponUsedRecordMapper.selectCountByActivityIdAndStoreId(activity.getId(),req.getStoreId());
        if(storeCount >= activity.getGetQuantity()){
            return ResponseData.fail("该门店优惠券已被领取完");
        }


        String code = null;

        List<ActCouponActivityCode> codeList = actCouponActivityCodeMapper.selectByActivityIdAndStatus(activity.getId(),(byte) 0);
        if(codeList.isEmpty() || codeList.size() == 0){
            //优惠券领取完, 查找是否存在领取未使用的优惠券, 取最早的一张
            ActCouponGetRecord actCouponGetRecord = actCouponGetRecordMapper.selectNewByActivityIdAndStatus(activity.getId());
            if(StringUtils.isEmpty(actCouponGetRecord)){
                return ResponseData.fail("优惠券已使用完");
            }
            ActCouponBaseInfo actCouponBaseInfo = actCouponBaseInfoMapper.selectByPrimaryKey(activity.getCouponBaseId());
            //更新使用记录
//            BeanUtils.copyProperties(activity,actCouponGetRecord);

            actCouponGetRecord.setUserStoreId(req.getStoreId());
            actCouponGetRecord.setUpdatedAt(new Date());

            codeResp.setCouponType(actCouponBaseInfo.getCouponType());
            codeResp.setAmount(actCouponBaseInfo.getAmount());

            actCouponGetRecordMapper.updateByPrimaryKeySelective(actCouponGetRecord);

            code = actCouponGetRecord.getCode();

        }else{
            //随机取一张优惠券
            int max = codeList.size(),min = 0;
            int index = (int) (Math.random()*(max-min)+min);
            ActCouponActivityCode activityCode = codeList.get(index);
            ActCouponBaseInfo actCouponBaseInfo = actCouponBaseInfoMapper.selectByPrimaryKey(activity.getCouponBaseId());
            //添加领取优惠券记录
            ActCouponGetRecord actCouponGetRecord = new ActCouponGetRecord();
            BeanUtils.copyProperties(activity,actCouponGetRecord);
            actCouponGetRecord.setId(null);
            actCouponGetRecord.setActivityId(activity.getId());
            actCouponGetRecord.setCode(activityCode.getCode());
            actCouponGetRecord.setUserStoreId(req.getStoreId());
            actCouponGetRecord.setStatus((byte) 0);
            actCouponGetRecord.setCreatedAt(new Date());
            actCouponGetRecord.setCouponType(actCouponBaseInfo.getCouponType());
            actCouponGetRecord.setAmount(actCouponBaseInfo.getAmount());

            codeResp.setCouponType(actCouponBaseInfo.getCouponType());
            codeResp.setAmount(actCouponBaseInfo.getAmount());

            actCouponGetRecordMapper.insertSelective(actCouponGetRecord);

            //更新code表
            ActCouponActivityCode activityCode1 = new ActCouponActivityCode();
            activityCode1.setId(activityCode.getId());
            activityCode1.setStatus((byte) 1);
            activityCode1.setUpdatedAt(new Date());
            actCouponActivityCodeMapper.updateByPrimaryKeySelective(activityCode1);

            code = activityCode.getCode();
        }

        codeResp.setCode(code);
        codeResp.setActivityName(activity.getActivityName());
        codeResp.setMaxDiscountAmount(activity.getMaxDiscountAmount());
        codeResp.setMinConsumeAmount(activity.getMinConsumeAmount());
        codeResp.setEndTime(activity.getEndTime());


        return ResponseData.success(codeResp);
    }

    @Override
    public ActCouponGetRecord selectGetRecordByCode(String code) {
        return actCouponGetRecordMapper.selectByCode(code);
    }

    @Override
    public ActCouponGetRecord selectGetRecordByCodeAndStatusAndDate(String code) {
        return actCouponGetRecordMapper.selectByCodeAndStatusAndDate(code);
    }

    @Override
    public int updateGetRecord(ActCouponGetRecord actCouponGetRecord) {
        return actCouponGetRecordMapper.updateByPrimaryKeySelective(actCouponGetRecord);
    }

    @Override
    public int countUsedCouponByStoreId(Long activityId, Long storeId) {
        return actCouponUsedRecordMapper.selectCountByActivityIdAndStoreId(activityId,storeId);
    }

    @Override
    public int updateActCouponActivityCode(String code, Byte status) {
        return actCouponActivityCodeMapper.updateStatusByCode(code,status);
    }

    @Override
    public int updateUsedRecord(ActCouponUsedRecord actCouponUsedRecord) {
        return actCouponUsedRecordMapper.updateByPrimaryKeySelective(actCouponUsedRecord);
    }

    @Override
    public int insertUsedRecord(ActCouponUsedRecord actCouponUsedRecord) {
        return actCouponUsedRecordMapper.insertSelective(actCouponUsedRecord);
    }

}
